//Copyright (c) 2006-2007 Microsoft Corporation.  All rights reserved
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Xml;

using InvocationFramework.Common.Resources;

namespace InvocationFramework.Core.Configuration
{
    /// <summary>
    /// Clase que procesa la seccion de configuracion del framework
    /// </summary>
    internal sealed class SectionHandler : IConfigurationSectionHandler
    {
        #region IConfigurationSectionHandler Members

        /// <summary>
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="configContext"></param>
        /// <param name="section"></param>
        /// <returns></returns>
        public object Create( object parent, object configContext, XmlNode section )
        {
            if ( section == null )
                throw new ConfigurationErrorsException( Texts.SectionHandlerSectionNull );

            #region General Configuration

            bool enablePerformanceCounters = false;
            if ( section.Attributes[ "enablePerformanceCounters" ] != null )
                enablePerformanceCounters = Convert.ToBoolean( section.Attributes[ "enablePerformanceCounters" ].Value, CultureInfo.InvariantCulture );

            bool enableLocalCatalog = true;
            if ( section.Attributes[ "enableLocalCatalog" ] != null )
                enableLocalCatalog = Convert.ToBoolean( section.Attributes[ "enableLocalCatalog" ].Value, CultureInfo.InvariantCulture );

            double localCatalogInvalidationInterval = 0;
            if ( section.Attributes[ "localCatalogInvalidationInterval" ] != null && !String.IsNullOrEmpty( section.Attributes[ "localCatalogInvalidationInterval" ].Value ) )
                localCatalogInvalidationInterval = Convert.ToDouble( section.Attributes[ "localCatalogInvalidationInterval" ].Value, CultureInfo.InvariantCulture );

            #endregion

            #region Caller Adapters

            XmlNodeList callerNodeList = section.SelectNodes( "caller/serviceAdapters/serviceAdapter" );
            List<AdapterElement> callerAdapters = LoadAdapters( callerNodeList );

            #endregion

            #region Publisher Adapters

            XmlNodeList publisherNodeList = section.SelectNodes( "publisher/serviceAdapters/serviceAdapter" );
            List<AdapterElement> publisherAdapters = LoadAdapters( publisherNodeList );

            #endregion

            return new ConfigurationInformation( enablePerformanceCounters, enableLocalCatalog, localCatalogInvalidationInterval, callerAdapters, publisherAdapters );
        }

        #endregion

        #region Private Methods

        private static List<AdapterElement> LoadAdapters( XmlNodeList nodeList )
        {
            if ( nodeList != null )
            {
                List<AdapterElement> adapters = new List<AdapterElement>( );

                foreach ( XmlNode node in nodeList )
                {
                    if ( node.Attributes[ "id" ] == null &&
                         node.Attributes[ "order" ] == null &&
                         node.Attributes[ "enabled" ] == null &&
                         node.Attributes[ "type" ] == null )
                        throw new ConfigurationErrorsException( Texts.SectionHandlerAdapterNodeAttributesNull );

                    AdapterElement item = new AdapterElement( );

                    item.Id = node.Attributes[ "id" ].Value;
                    item.Order = Convert.ToInt32( node.Attributes[ "order" ].Value, CultureInfo.InvariantCulture );
                    item.Enabled = Convert.ToBoolean( node.Attributes[ "enabled" ].Value, CultureInfo.InvariantCulture );
                    item.Type = node.Attributes[ "type" ].Value;

                    if ( node.ChildNodes != null )
                    {
                        foreach ( XmlNode childnode in node.ChildNodes )
                        {
                            if ( childnode.NodeType == XmlNodeType.Element )
                            {
                                item.AdapterConfiguration = childnode;
                                break;
                            }
                        }
                    }

                    adapters.Add( item );
                }

                return adapters;
            }
            else
            {
                return null;
            }
        }

        #endregion
    }
}